package com.wlz.jvm2;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;

/**
 *  元空间溢出示例
 */
public class MetaspaceOutOfMemoryErrorExample {

    // JVM设置
    // -XX:+PrintGCDetails -XX:MaxMetaspaceSize=64m -XX:MetaspaceSize=32m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/wlz/Desktop/jvm.dump
    // -XX:+PrintGCDetails -XX:MaxMetaspaceSize=64m -XX:MetaspaceSize=32m -XX:+HeapDumpOnOutOfMemoryError -XX:-UseGCOverheadLimit -XX:HeapDumpPath=/Users/wlz/Desktop/jvm.dump
    public static void main(String[] args) {
        try {
            // 使用Javassist库生成大量的类
            generateClasses();
//        } catch (Exception e) {
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }catch (Exception e) {
            // 捕获其他异常
            e.printStackTrace();
        }
    }

    private static void generateClasses() throws Exception {
        ClassPool classPool = ClassPool.getDefault();
        for (int i = 0; ; i++) {
            // 创建新的类
            CtClass ctClass = classPool.makeClass("GeneratedClass" + i);

            // 添加一个字段
            CtField field = new CtField(CtClass.intType, "field" + i, ctClass);
            ctClass.addField(field);

            // 添加一个方法
            CtMethod method = CtMethod.make("public void setField" + i + "(int value) { this.field" + i + " = value; }", ctClass);
            ctClass.addMethod(method);

            // 添加另一个方法
            method = CtMethod.make("public int getField" + i + "() { return this.field" + i + "; }", ctClass);
            ctClass.addMethod(method);

            // 将类加载到元空间
            ctClass.toClass();
        }
    }
}
